package com.allwees.bs.c.module.sys.service.impl;

import com.octo.captcha.Captcha;
import com.octo.captcha.image.gimpy.Gimpy;
import com.octo.captcha.service.AbstractCaptchaService;
import com.octo.captcha.service.captchastore.CaptchaStore;
import com.octo.captcha.service.multitype.GenericManageableCaptchaService;
import com.allwees.bs.c.module.sys.service.ICaptchaService;
import com.allwees.core.common.util.octo.MyEngine;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.util.UUID;

@Service
public class CaptchaServiceImpl implements ICaptchaService {
	static int minGuarantedStorageDelayInSeconds = 180;

	static int maxCaptchaStoreSize = 100000;

	static int captchaStoreLoadBeforeGarbageCollection = 75000;

	private static GenericManageableCaptchaService service = null;

	static {
		service = new GenericManageableCaptchaService(new MyEngine(),
				minGuarantedStorageDelayInSeconds,
				maxCaptchaStoreSize,
				captchaStoreLoadBeforeGarbageCollection);
	}

	public String captcha(HttpServletResponse response) throws Exception {
		GenericManageableCaptchaService service = getImageService();
		String tmp = UUID.randomUUID().toString();
		BufferedImage bi = service.getImageChallengeForID(tmp);
		CaptchaStore store = (CaptchaStore) storeFiled.get(service);
		Captcha captcha = store.getCaptcha(tmp);
		String code = (String) responseField.get(captcha);

		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		response.setHeader("code", code);

		ServletOutputStream sos = response.getOutputStream();
		ImageIO.write(bi, "jpg", sos);
		try {
			sos.flush();
		} finally {
			sos.close();
		}
		return code;
	}

	private GenericManageableCaptchaService getImageService() {
		return service;
	}

	static Field storeFiled = null;

	static Field responseField = null;

	static {
		try {
			storeFiled = AbstractCaptchaService.class.getDeclaredField("store");
			storeFiled.setAccessible(true);
		} catch(NoSuchFieldException e) {
			e.printStackTrace();
		}
		try {
			responseField = Gimpy.class.getDeclaredField("response");
			responseField.setAccessible(true);
		} catch(NoSuchFieldException e) {
			e.printStackTrace();
		}
	}

}
